package com.yql.biz.core.aspect;

import cn.hutool.json.JSONUtil;
import com.yql.common.utils.logs.CommonLogUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @ClassName: WebLogAspect
 * @Description: 入参 出参日志打印
 * @Date: 2021-06-29
 **/
@Aspect
@Component
public class WebLogAspect {

    private final static Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    @Pointcut("execution(public * com.yql..*.controller..*.*(..)) && !execution(* com.yql.common.core.controller.BaseController.*(..)))")
    //切入点描述 这个是controller包的切入点
    public void webLog() {
    }

    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();

        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        //String uri = request.getRequestURI();
        String queryString = request.getQueryString();
        Object[] args = pjp.getArgs();
        String params = "";
        //获取请求参数集合并进行遍历拼接
        if (args.length > 0) {
            if ("POST".equals(method)) {
                Object object = args[0];
                List<Object> paramList = new ArrayList<>();
                for (Object obj : args) {
                    if (obj instanceof MultipartFile) {
                        logger.info("uri={},参数包含文件流,日志输出过滤", request.getRequestURI());
                        continue;
                    } else if (obj instanceof HttpServletResponse) {
                        continue;
                    } else if (obj instanceof HttpServletRequest) {
                        continue;
                    }
                    paramList.add(obj);
                }
                params = JSONUtil.toJsonStr(paramList);
            } else if ("GET".equals(method)) {
                params = URLDecoder.decode(queryString, "UTF-8");
            }
        }
        StringBuffer reqLog = new StringBuffer();
        reqLog.append(" 【请求类型】:").append(request.getMethod()).append(" 【执行的方法】:").append(request.getRequestURL().toString()).append(" 【参数为】").append(params);
        CommonLogUtil.info(new Throwable(), "{}", reqLog);

        Object result = pjp.proceed();// result的值就是被拦截方法的返回值

        StringBuffer respLog = new StringBuffer();
        respLog.append(" 【执行的方法】:").append(request.getRequestURL().toString()).append(" 【响应为】").append(JSONUtil.toJsonStr(result));
        CommonLogUtil.info(new Throwable(), "{}", respLog);
        return result;
    }


}
